﻿using Cat.DataAccess;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

namespace CodeHelper
{
    class Program
    {
        private static string jsTempl = @"var pageObject = {
    requestId: '',   
    total: 0,
    listWrap: $('#listWrap'),
    pagerUrl: 'XXX.asmx/GetList',
    pagerPamater: {
        searchKey: '',
        currentPage: 1,
        pageSize: 20
    },
    preBtn: $('#preBtn'),
    nextBtn: $('#nextBtn'),
    addDialogBtn: $('#addDialog'),
    closeDialogBtn: $('#cancle'),
    submitBtn: $('#submitBtn'),
    submitPamater: {},
    addPamater: {},
    addSubmitUrl: 'XXX.asmx/Submit',
    modifyShowDialogBtn: null,
    modfiyPamater: {},
    modifySubmitUrl: 'XXX.asmx/Submit',
    getDetailUrl: '',
    isModify:false,
    initPageObject: function () {
        pageJs.requestId = this.requestId;
        this.initDialog();
        this.preBtn.live('click', pageObject.getPrePage);//上一页事件
        this.nextBtn.live('click', pageObject.getNextPage);//下一页事件
        this.closeDialogBtn.live('click', pageObject.closeDialog);
        this.getPagerList();//由于要绑定编辑按钮事件，所以列表初始化放在前面
        this.addDialogBtn.on('click', pageObject.initAddDialog);//添加对话框展示      
        this.submitBtn.one('click', pageObject.infoSubmit);//数据提交
        this.closeDialogBtn.live('click', pageObject.closeDialog);//关闭对话框
    },
    showDialog: function () {
         pageJs.showDialog('addDialogWrap');
    },
    closeDialog: function () {
        pageJs.closeDialog(function () {
            $('.需要清理数据的控件样式名').val('');
        });
    },
    initDialog: function () {//初始对话框必要元素
        pageObject.isModify = false;
       
    },
    initAddDialog: function () {//为添加书对话框添加必要元素
        pageObject.isModify = false;
        pageObject.showDialog();
    },
    initModifyDialog: function () {//为修改对话框添加必要元素，初始化要修改的数据
        pageObject.isModify = true;
        var infoid = $(this).attr('infoId');
        pageJs.loadAjaxFun(pageObject.getDetailUrl, { infoId: infoid}, function (data) {
            if (data.ActionResult) {
                //成功后
                for (items in data.Data){//遍历对象属性进行赋值
                    $('#' + items).val(data.Data[items]);
                }
        pageObject.showDialog();
            } else {
                //操作失败
            };
        });       
    },
    modifyInitPamater: function () {//获取修改要提交的参数
        for (items in pageObject.modfiyPamater) {//遍历对象属性进行赋值
            pageObject.modfiyPamater[items] = $('#' + items).val();
        };
    },
    addInitPamater: function () {//获取添加要提交的参数
        pageObject.addPamater = {$3};
    },
    infoSubmit: function () {//提交对话框数据
         if (pageObject.isModify) {
            pageObject.modifyInitPamater();
            pageObject.submitPamater = pageObject.modfiyPamater;
            pageObject.submitUrl = pageObject.modifySubmitUrl;
        }
        else {
            pageObject.addInitPamater();
            pageObject.submitPamater = pageObject.addPamater;
            pageObject.submitUrl = pageObject.addSubmitUrl;
        }
        pageJs.loadAjaxFun(pageObject.submitUrl, pageObject.submitPamater, function (data) {
            if (data.ActionResult) {
                //成功后
                pageObject.getPagerList();
                pageObject.closeDialog();
            } else {
                //操作失败
            };
 pageObject.submitBtn.one('click', pageObject.infoSubmit);//数据提交
        });
    },
    getPrePage: function () {
        if (pageObject.pagerPamater.currentPage > 1) {
            pageObject.pagerPamater.currentPage = pageObject.pagerPamater.currentPage - 1;
            pageObject.getPagerList();
        }
    },
    getNextPage: function () {
        pageObject.pagerPamater.currentPage = pageObject.pagerPamater.currentPage + 1;
        pageObject.getPagerList();
    },
    getPagerList: function () {
        pageJs.loadAjaxFun(pageObject.pagerUrl, pageObject.pagerPamater, function (data) {
            if (data.ActionResult) {
                var listHtml = '<li>{$1}';
                var temp;
                 if (data.Data.length > 0) {
                    pageObject.listWrap.html('');
                     for (var i = 0; i < data.Data.length; i++) {
                    temp = listHtml.replace('$n', data.Data[i].N);
                   {$2}
                    pageObject.listWrap.append(temp);
                    pageObject.listWrap.append('<span><a class=\'modifyShow\' infoId=' + data.Data[i].Id + ' href=\'javascript:void(0)\'>编辑</a></span></li>');    }                pageObject.modifyShowDialogBtn = $('.modifyShow');//获取列表对象               
                 pageObject.modifyShowDialogBtn.on('click', pageObject.initModifyDialog);//修改对话框展示事件绑定  
 pageObject.total = data.Total; 
                }else
                {
                     pageObject.pagerPamater.currentPage = pageObject.pagerPamater.currentPage - 1;
                }
               
            }
            else{
                alert('请求无数据')
                 pageObject.pagerPamater.currentPage = pageObject.pagerPamater.currentPage - 1;
            }
        });
    }
};";
        private static string listHtmlTempl = "<!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\"><head>    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />    <title></title><link href=\"http://mr.1rock.net/plus/fancyboxv2/jquery.fancybox.css\" rel=\"stylesheet\" /></head><body>    <div>        <div class=\"loading\" style=\"display: none\">加载中.......</div>        <div><span><a id=\"addDialog\" href=\"javascript:void(0)\">添加项目</a></span></div>        <div id=\"dataContent\">            <ul id=\"listWrap\">                <li> </li>            </ul>            <span><a id=\"pre\">上一页</a></span><span><a id=\"next\">下一页</a></span>        </div>    </div>      <div id=\"addDialogWrap\" style=\"display: none;width:500px;height:450px;\">        <h1>对话框标题</h1>$1\n<div><span><a id=\"submitBtn\" href=\"javascript:void(0)\">提交</a></span><span><a id=\"cancle\" href=\"javascript:void(0)\">取消</a></span></div>\n</div><script src=\"http://mr.1rock.net/lib/jquery-1.8.2.min.js\"></script>    <script src=\"http://mr.1rock.net/plus/fancyboxv2/jquery.fancybox.pack.js\"></script>    <script src=\"http://mr.1rock.net/lib/pageJs.js\"></script>    <script src=\"AgreementList.js\"></script>    <script type=\"text/javascript\">        pageObject.requestId = '<%=Cat.Util.SerurityHelper.GetTimeToken()%>';        pageObject.initPageObject();    </script>            </body></html>";
        private static string ProviderTempl = "using Cat.BussinessService.Dal;\nusing Cat.Util;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nnamespace Cat.BussinessService\n{  \n  public class Provider  \n    {    \n    public BaseModel.GridPager<BaseModel.$> GetPagerList(string searchName, DateTime? startTime, DateTime? endTime, BaseModel.GridPagerParam param, long operationBy, bool isUnion = false)        {            ArgumentHelper.AssertInRange(\"operationBy\", (int)operationBy, 1, int.MaxValue);\n            startTime= startTime.HasValue ? startTime.Value : DateTime.Now.AddDays(-1.0);\n            endTime = endTime.HasValue ? endTime.Value : DateTime.Now.AddDays(1.0);\n            var r = new BaseModel.GridPager<BaseModel.$>(false);\n            int total = 0;\n           if (isUnion)            {                r.Data = $Dal.GetUnion(searchName, startTime.Value, endTime.Value, param, operationBy, out total);\n               r.ActionResult = (r.Data != null) ? true : false;\n           }            else            {                r.Data = $Dal.GetJoin(searchName, startTime.Value, endTime.Value, param, operationBy, out total);\n               r.ActionResult = (r.Data != null) ? true : false;\n           }             return r;\n   }        public BaseModel.OperationResult<BaseModel.$> GetDetail(int operationBy, int $Id)        {            ArgumentHelper.AssertInRange(\"operationBy\", (int)operationBy, 1, int.MaxValue);\n          // ArgumentHelper.AssertInRange(\"$Id\", $Id, 1, int.MaxValue);\n           var r = new BaseModel.OperationResult<BaseModel.$>();\n           r.Data = $Dal.GetDetail(operationBy, $Id);\n           r.ActionResult = (r.Data != null) ? true : false;\n           return r;\n       }        public BaseModel.OperationResult<int> Create(BaseModel.$ info)        {           // ArgumentHelper.AssertNotNullOrEmpty(info.$Name);\n              var r = new BaseModel.OperationResult<int>();\n           r.Data = $Dal.Create(info);\n           r.ActionResult = (r.Data>0) ? true : false;\n           return r;\n       }        public BaseModel.ActionMsg Modify(BaseModel.$ info)        {           // ArgumentHelper.AssertNotNullOrEmpty(info.infoName);\n             var r = new BaseModel.ActionMsg();\n           r.ActionResult = $Dal.Modify(info);\n           return r;\n       }           public BaseModel.ActionMsg IsShow(int operationBy, int infoId, bool isShow)        {            ArgumentHelper.AssertInRange(\"operationBy\", operationBy, 1, int.MaxValue);\n           //ArgumentHelper.AssertInRange(\"infoId\", infoId, 1, int.MaxValue);\n           var r = new BaseModel.ActionMsg();\n           r.ActionResult = $Dal.IsShow(operationBy, infoId, isShow);\n           return r;\n       }        public BaseModel.ActionMsg IsBatchShow(int operationBy, List<int> infoIds, bool isShow)        {            ArgumentHelper.AssertInRange(\"operationBy\", operationBy, 1, int.MaxValue);\n           ArgumentHelper.AssertNotNull<List<int>>(infoIds);\n           var r = new BaseModel.ActionMsg();\n           r.ActionResult = $Dal.IsBatchShow(operationBy, infoIds, isShow);\n           return r;\n       }    }}";
        private static string dalTempl = "using Cat.BaseModel;using Cat.DataAccess;using Cat.Util;using MySql.Data.MySqlClient;using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Cat.BussinessService.Dal{    internal class $Dal:MysqlDatabaseFactory<BaseModel.$>    {        private static string _DatabaseName = \"Cat_bank\";\n       internal static List<BaseModel.$> GetUnion(string searchName, DateTime startTime, DateTime endTime, BaseModel.GridPagerParam param, long operationBy, out int total)        {            StringBuilder strSql = new StringBuilder();\n           strSql.Append(\"select * FROM $ where ($Name like CONCAT('%',?searchName,'%') or (createTime BETWEEN ?startTime and ?endTime)) and createBy=?operationBy\");\n           strSql.Append(\" order by createTime desc\");\n           strSql.Append(\" limit \");\n           strSql.Append(((param.CurrentPage - 1) * param.PageSize).ToString() + \",\" + param.PageSize.ToString());\n           total = 0;\n           var parameters = new List<MySqlParameter>();\n            parameters.Add(new MySqlParameter(\"?searchName\", searchName));\nparameters.Add(new MySqlParameter(\"?startTime\", startTime));parameters.Add(new MySqlParameter(\"?endTime\", endTime));parameters.Add(new MySqlParameter(\"?operationBy\", operationBy));\n           \n parameters.Add(new MySqlParameter(\"?CurrentPage\", param.CurrentPage));\n          \n parameters.Add(new MySqlParameter(\"?PageSize\", param.PageSize));\n   List<BaseModel.$> resultList = GetListByReader<BaseModel.$>(_DatabaseName, parameters, strSql.ToString(), CommandType.Text, delegate(MySqlDataReader dataReader, List<BaseModel.$> result)            {                while (dataReader.Read()){ var temp = new BaseModel.$(){  {*11} };result.Add(temp);}});  return resultList;\n       }        internal static List<BaseModel.$> GetJoin(string searchName, DateTime startTime, DateTime endTime, BaseModel.GridPagerParam param, long operationBy, out int total)        {            StringBuilder strSql = new StringBuilder();\n           strSql.Append(\"select * FROM $ where $Name like CONCAT('%',?searchName,'%') and (createTime BETWEEN ?startTime AND ?endTime) and createBy=?operationBy\");\n           strSql.Append(\" order by createTime desc\");\n           strSql.Append(\" limit \");\n           strSql.Append(((param.CurrentPage - 1) * param.PageSize).ToString() + \",\" + param.PageSize.ToString());\n           total = 0;\n           var parameters = new List<MySqlParameter>();\n           parameters.Add(new MySqlParameter(\"?searchName\", searchName));\n           parameters.Add(new MySqlParameter(\"?startTime\", startTime));\n           parameters.Add(new MySqlParameter(\"?endTime\", endTime));\n           parameters.Add(new MySqlParameter(\"?operationBy\", operationBy));\n           parameters.Add(new MySqlParameter(\"?CurrentPage\", param.CurrentPage));\n           parameters.Add(new MySqlParameter(\"?PageSize\", param.PageSize));\n  List<BaseModel.$> resultList = GetListByReader<BaseModel.$>(_DatabaseName, parameters, strSql.ToString(), CommandType.Text, delegate(MySqlDataReader dataReader, List<BaseModel.$> result)            {                while (dataReader.Read()){ var temp = new BaseModel.$(){  {*11} };result.Add(temp);}});       return resultList;\n       }        internal static BaseModel.$ GetDetail(int operationBy, int id)        {                    List<MySqlParameter> parameters = new List<MySqlParameter>();\nparameters.Add(new MySqlParameter(\"?operationBy\", operationBy));\n parameters.Add(new MySqlParameter(\"?id\", id));\n       BaseModel.$ result = GetDataByReader<BaseModel.$>(_DatabaseName, parameters, \"select * from $ where id=?id;\", CommandType.Text, delegate(MySqlDataReader dataReader)            {                if (dataReader.Read())                {                    var r = new BaseModel.$();    {*1}                    return r;                }                else                    return null;            });    return result;\n       }        internal static int Create(BaseModel.$ model)        {                   List<MySqlParameter> parameters = new List<MySqlParameter>();\n{*4}\n;return DatabaseFactory.GetPrimarykey(_DatabaseName, parameters.ToArray(), \"insert into $({*2})  values ({*3});SELECT  @@IDENTITY as id\", CommandType.Text);\n       }        internal static bool Modify(BaseModel.$ model)        {             List<MySqlParameter> parameters = new List<MySqlParameter>();\n{*4}\nreturn DatabaseFactory.ExecuteNonQuery(_DatabaseName, parameters, \"update $ set {*5} where userID=?userID;\", CommandType.Text) > 0 ? true : false;\n       }    }}";
       
        static void Main(string[] args)
        {
            //获取所有表对象
            List<string> tables = new List<string>();
            tables.Add("cb_product");        
            Console.WriteLine("加载表");
            //using (var dataReader = DatabaseFactory.GetDataReader("Cat_bank", null,"select DISTINCT table_name from information_schema.COLUMNS where table_schema ='cat_bank';", CommandType.Text))
            //{
            //    while (dataReader.Read())
            //    {
            //        tables.Add(dataReader["table_name"].ToString());
            //    }
            //}
            Console.WriteLine("开始生成");
            //循环生成代码
            tables.ForEach(a => {
                Console.WriteLine("开始生成" + a);
                var dic = new Dictionary<string, string>();
                using (var dataReader = DatabaseFactory.GetDataReader("Cat_bank", null, "select COLUMN_NAME,DATA_TYPE from information_schema.COLUMNS where TABLE_NAME='"+a+"' and table_schema = 'cat_bank';", CommandType.Text))
                {
                    while (dataReader.Read())
                    {
                        dic.Add(dataReader["COLUMN_NAME"].ToString(), dataReader["DATA_TYPE"].ToString());
                    }
                }
                Console.WriteLine("开始生成html");
                File.AppendAllText(@"D:\codehelper\" + a + ".html", createListPage(a, dic));
                Console.WriteLine("开始生成js");
                File.AppendAllText(@"D:\codehelper\" + a + ".js", createListJs(a, dic));
                Console.WriteLine("开始生成cs");
                File.AppendAllText(@"D:\codehelper\" + a + "Provider.cs", createProvider(a, dic));
                Console.WriteLine("开始生成cs");
                File.AppendAllText(@"D:\codehelper\" + a + "Dal.cs", createDal(a, dic));
                Console.WriteLine("开始生成cs");
                File.AppendAllText(@"D:\codehelper\" + a + "Model.cs", createModel(a, dic));
            });
        }
        public static string createListPage(string tableName,Dictionary<string, string> columns)
        {
            string mt = "<div>项目名:<input type=\"text\" id=\"$\" name=\"$\" value=\"\" class=\"addval\" /></div>";
            StringBuilder s = new StringBuilder();
            foreach (var k in columns)
            {
                s.Append(mt.Replace("$", k.Key));
            }
            return listHtmlTempl.Replace("$1",s.ToString());
        }
        public static string createListJs(string tableName, Dictionary<string, string> columns)
        {
            string mt = "<label>$n</label>| ";
            string mt1 = " temp = temp.replace('{$$n}', data.Data[i].$n);";
            string mt2 = "@: $(\"#*\").val(),";
            StringBuilder s = new StringBuilder();
            StringBuilder s1 = new StringBuilder();
            StringBuilder s2 = new StringBuilder();
            foreach (var k in columns)
            {
                s.Append(mt.Replace("$n","{$"+k.Key+"}"));
                s1.Append(mt1.Replace("$n", k.Key));
                s2.Append(mt2.Replace("*", k.Key).Replace("@", k.Key.ToLower()));
            }
            return jsTempl.Replace("{$1}", s.ToString()).Replace("{$2}", s1.ToString()).Replace("$3", s2.ToString().TrimEnd(','));
        }

        public static string createProvider(string tableName, Dictionary<string, string> columns)
        {
            return ProviderTempl.Replace("$",tableName);
        }
        public static string createDal(string tableName, Dictionary<string, string> columns)
        {
            string html = dalTempl.Replace("$", tableName);
            html = html.Replace("{*1}", getP1(columns));
            html = html.Replace("{*11}", getP11(columns));
            html = html.Replace("{*2}", getP2(columns));
            html = html.Replace("{*3}", getP3(columns));
            html = html.Replace("{*4}", getP4(columns));
            html = html.Replace("{*5}", getP5(columns));
            return html;
        }

        private static string getP5(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            string t = "$=?$,";
            foreach (var k in columns)
            {
                s.Append(t.Replace("$", k.Key));
            };
            return s.ToString().TrimEnd(',');
        }
       
        private static string getP1(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            foreach(var k in columns){
                switch (k.Value)
                {
                    case "int":
                        s.Append(" r." + k.Key + " = dataReader.GetInt32(\"" + k.Key + "\");");
                        break;
                    case "varchar":
                        s.Append(" r." + k.Key + " = dataReader[\"" + k.Key + "\"].ToString();");
                        break;
                    case "text":
                        s.Append(" r." + k.Key + " = dataReader[\"" + k.Key + "\"].ToString();");
                        break;
                    case "longtext":
                        s.Append(" r." + k.Key + " = dataReader[\"" + k.Key + "\"].ToString();");
                        break;
                    case "char":
                        s.Append(" r." + k.Key + " = dataReader[\"" + k.Key + "\"].ToString();");
                        break;
                    case "tinyint":
                        s.Append(" r." + k.Key + " = dataReader.GetByte(\"" + k.Key + "\");");
                        break;
                    case "datetime":
                        s.Append(" r." + k.Key + " = dataReader.GetDateTime(\"" + k.Key + "\");");
                        break;
                    case "decimal":
                        s.Append(" r." + k.Key + " = dataReader.GetDecimal(\"" + k.Key + "\");");
                        break;
                    case "float":
                        s.Append(" r." + k.Key + " = dataReader.GetFloat(\"" + k.Key + "\");");
                        break;
                }               
            }
            return s.ToString().TrimEnd(',');
        }
        private static string getP11(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            foreach (var k in columns)
            {
                switch (k.Value)
                {
                    case "int":
                        s.Append(" " + k.Key + " = dataReader.GetInt32(\"" + k.Key + "\"),\n");
                        break;
                    case "varchar":
                        s.Append("" + k.Key + " = dataReader[\"" + k.Key + "\"].ToString(),\n");
                        break;
                    case "text":
                        s.Append("" + k.Key + " = dataReader[\"" + k.Key + "\"].ToString(),\n");
                        break;
                    case "longtext":
                        s.Append("" + k.Key + " = dataReader[\"" + k.Key + "\"].ToString(),\n");
                        break;
                    case "char":
                        s.Append("" + k.Key + " = dataReader[\"" + k.Key + "\"].ToString(),\n");
                        break;
                    case "tinyint":
                        s.Append("" + k.Key + " = dataReader.GetByte(\"" + k.Key + "\"),\n");
                        break;
                    case "datetime":
                        s.Append("" + k.Key + " = dataReader.GetDateTime(\"" + k.Key + "\"),\n");
                        break;
                    case "decimal":
                        s.Append("" + k.Key + " = dataReader.GetDecimal(\"" + k.Key + "\"),\n");
                        break;
                    case "float":
                        s.Append("" + k.Key + " = dataReader.GetFloat(\"" + k.Key + "\"),\n");
                        break;
                }
            }
            return s.ToString().TrimEnd(',');
        }
        private static string getP2(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            foreach (var k in columns) {
                s.Append(k.Key + ",");
            }
            return s.ToString().TrimEnd(',');
        }
        private static string getP3(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            foreach (var k in columns)
            {
                s.Append("?"+k.Key + ",");
            }
            return s.ToString().TrimEnd(',');
        }
        private static string getP4(Dictionary<string, string> columns)
        {
            StringBuilder s = new StringBuilder();
            string t = "  parameters.Add(new MySqlParameter(\"?$\", model.$));\n";
             foreach (var k in columns)
            {
                s.Append(t.Replace("$",k.Key));
            }
            return s.ToString().TrimEnd(',');
        }
        public static string createModel(string tableName, Dictionary<string, string> columns)
        {
            string m = "using System;\n namespace Cat.BaseModel\n {\n public class $    { \n      * \n }\n}\n";
            StringBuilder s1 = new StringBuilder(m);
            StringBuilder s = new StringBuilder();
            string mp = " public {$1} {$2}{            get;set;        }\n";
            foreach (var k in columns)
            {
                switch (k.Value)
                {
                    case "int":
                        s.Append(mp.Replace("{$1}","int").Replace("{$2}",k.Key));
                        break;
                    case "varchar":
                        s.Append(mp.Replace("{$1}", "string").Replace("{$2}", k.Key));
                        break;
                    case "text":
                        s.Append(mp.Replace("{$1}", "string").Replace("{$2}", k.Key));
                        break;
                    case "longtext":
                        s.Append(mp.Replace("{$1}", "string").Replace("{$2}", k.Key));
                        break;
                    case "char":
                        s.Append(mp.Replace("{$1}", "string").Replace("{$2}", k.Key));
                        break;
                    case "tinyint":
                        s.Append(mp.Replace("{$1}", "byte").Replace("{$2}", k.Key));
                        break;
                    case "datetime":
                        s.Append(mp.Replace("{$1}", "DateTime").Replace("{$2}", k.Key));
                        break;
                    case "decimal":
                        s.Append(mp.Replace("{$1}", "decimal").Replace("{$2}", k.Key));
                        break;
                    case "float":
                        s.Append(mp.Replace("{$1}", "float").Replace("{$2}", k.Key));
                        break;
                }
            }
            return m.Replace("*",s.ToString()).Replace("$",tableName);
        }
    }
}
